#include <wx/string.h>
#include <wx/intl.h>
#include "note_filter.h"
#include "note.h"
#include "util.h"
#include "unicode.h"
#include "keyword.h"

bool NoteFilter::KeywordsFromString(const wxString& from)
{
    return ::KeywordsFromString(from, this->keywords);
}


wxString NoteFilter::KeywordsToString() const
{
    wxString result;
    for (unsigned x=0; x<keywords.size(); x++) {
        if (x != 0)
            result += ", ";
        result += keywords[x];
    }
    return result;
}

static bool MatchesKeyword(const wxString& txt, const wxString& keyword)
{
    if (keyword.IsEmpty())
        return true;
    wxString txt_upper = txt;
    txt_upper.MakeUpper();
    wxString keyword_upper = keyword;
    keyword_upper.MakeUpper();
    return (txt_upper.Find(keyword_upper) != -1);
}

bool NoteFilter::MatchesKeywords(const wxString& txt) const
{
    for (unsigned x=0; x<keywords.size(); x++)
        if (!MatchesKeyword(txt, keywords[x]))
            return false;
    return true;
}

bool NoteFilter::Matches(const Note& n) const
{
    // check date
    if (!from_date.IsEmpty() && n.CompareDateTo(from_date)<0) {
        return false;
    }
    if (!n.date.IsEmpty() && !to_date.IsEmpty() && n.CompareDateTo(to_date)>=0) {
        return false;
    }

    // check keywords
    if (!MatchesKeywords(n.ParseAllKeywords()))
        return false;

    // check body (in both note body and caption)
    if (!body.IsEmpty() && !wxString_ContainsI(n.text, body) && !wxString_ContainsI(n.caption, body))
        return false;

    return true;
}

bool CheckFilterDate(const wxString& date)
{
    return CheckDate(date);
}

wxString NoteFilter::ToString() const
{
    bool first=true;
    wxString result = "NoteFilter(";
    if (keywords.size()==1) {
        result += wxString::Format("keyword=%s", keywords[0]);
        first = false;
    }
    if (keywords.size()>1) {
        result += "keywords=[";
        for (unsigned x=0; x<keywords.size(); x++) {
            if (x>0) result += ", ";
            result += keywords[x];
        }
        result += ']';
        first = false;
    }
    if (!from_date.IsEmpty()) {
        if (!first) result += ", ";
        result += wxString::Format("from=%s", from_date);
        first = false;
    }
    if (!to_date.IsEmpty()) {
        if (!first) result += ", ";
        result += wxString::Format("to=%s", to_date);
        first = false;
    }
    if (!body.IsEmpty()) {
        if (!first) result += ", ";
        result += wxString::Format("body='%s'", body);
        first = false;
    }
    if (max_notes != NOTE_FILTER_DEFAULT_MAX) {
        if (!first) result += ", ";
        result += wxString::Format("max=%ld", max_notes);
        first = false;
    }
    result += ')';
    return result;
}

bool NoteFilter::CheckKeywordsString(const wxString& from)
{
    std::vector<wxString> dummy_keywords;
    return ::KeywordsFromString(from, dummy_keywords);
}
